#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "calc.h"

class MockAdder : public Adder {
public:
    MOCK_METHOD(int, Sum, (int a, int b), (override));
};

class CalcTest : public testing::Test {
public:
    static void SetUpTestSuite()
    {
        adder = new Adder();
        calc = new Calc(adder);

        mockAdder = new MockAdder();
        mockCalc = new Calc(mockAdder.GetRefPtr());
    }

    static void TearDownTestSuite()
    {
        adder = nullptr;
        calc = nullptr;
        mockAdder = nullptr;
        mockCalc = nullptr;
    }

    static inline sptr<Adder> adder = nullptr;
    static inline sptr<Calc> calc = nullptr;
    static inline sptr<MockAdder> mockAdder = nullptr;
    static inline sptr<Calc> mockCalc = nullptr;
};

TEST_F(CalcTest, Parse) {
    ASSERT_EQ(calc->Parse("123 + 345"), 123 + 345);
}

TEST_F(CalcTest, ParseFailure) {
    ASSERT_EQ(calc->Parse("123 + 345"), 123 + 345);
}

TEST_F(CalcTest, Mock) {
    testing::UnitTest::GetInstance()->current_test_info()->name();
    EXPECT_CALL(*mockAdder, Sum(testing::_, testing::_))
        .Times(3)
        .WillOnce(testing::Return(1 + 2))
        .WillOnce(testing::Return(1 + 2 + 3))
        .WillOnce(testing::Return(1 + 2 + 3 + 4));
    ASSERT_EQ(mockCalc->Parse("1+2+3+4"), 10);
}
